<?php
namespace app\api\service;

use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use DateTimeImmutable;
use Lcobucci\JWT\Token\Plain;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
use Lcobucci\JWT\Validation\Constraint\SignedWith;

class Token
{
	public static function getConfig ()
	{
		$configuration = Configuration::forSymmetricSigner(
			new Sha256(),
			InMemory::base64Encoded('YWFhc0pOU0RLSkJITktKU0RiamhrMTJiM2Joa2ox')
		);
		return $configuration;
	}


	/* 签发令牌 */
	public static function create ()
	{
		$config = self::getConfig();
		assert($config instanceof Configuration);
		$now = new DateTimeImmutable();

		$token = $config->builder()
			->issuedBy('www.ixcom.cn')
			->permittedFor('ixcom')
			->identifiedBy('123')
			->issuedAt($now)
			->canOnlyBeUsedAfter($now->modify('+1 minute'))
			->expiresAt($now->modify('+1 hour'))
			->withClaim('uid', 1)
			->withHeader('foo', 'bar')
			->getToken($config->signer(), $config->signingKey());
		return $token->toString();
	}
	
	public static function parse ( string $token)
	{
		$config = self::getConfig();
		assert($config instanceof Configuration);
		$token = $config->parser()->parse($token);
		assert($token instanceof Plain);
		dump($token->headers()); // Retrieves the token headers
        dump($token->claims()); // Retrieves the token claims
	}

	public static function validation(string $token)
	{
		$config = self::getConfig();
		assert($config instanceof Configuration);

		$token = $config->parser()->parse($token);
		assert($token instanceof Plain);

		// 验证 jwt id 是否匹配
		$validate_jwt_id = new \Lcobucci\JWT\Validation\Constraint\IdentifiedBy('123');
		$config->setValidationConstraints($validate_jwt_id);

		//验证签发人url是否正确
        $validate_issued = new \Lcobucci\JWT\Validation\Constraint\IssuedBy('www.ixcom.cn');
        $config->setValidationConstraints($validate_issued);
        //验证客户端url是否匹配
        $validate_aud = new \Lcobucci\JWT\Validation\Constraint\PermittedFor('ixcom');
        $config->setValidationConstraints($validate_aud);

        //验证是否过期
        $timezone = new \DateTimeZone('Asia/Shanghai');
        $now = new \Lcobucci\Clock\SystemClock($timezone);
        $validate_jwt_at = new \Lcobucci\JWT\Validation\Constraint\ValidAt($now);
        $config->setValidationConstraints($validate_jwt_at);

        $constraints = $config->validationConstraints();

        try {
            $config->validator()->assert($token, ...$constraints);
        } catch (RequiredConstraintsViolated $e) {
            // list of constraints violation exceptions:
            dump($e->violations());
        }
	}
}